SPACE ENTER TABKEY RIGHT PGDNV NULL' CTRLD CTRLG CTRLHL CTRLSx CTRLV$ BLACK9 BLUEH GREEN] CYAN7 MAGENTA- YELLOW WHITEn BRIGHT BACKGROUND NORMALp HILITE CNORMAL CHILITE HELPTOP HELPBOT> HELPLEFTR HELPWID CARDSPERSCREENe LASTROW FALSE TRUEf CURSORON CURSOROFF TMPFILE DISKFILE NPERSON? NNOTE& NMONTH NDAYJ NYEARx NPHONE NSTREET NCITY NSTATE NFIELDS PERSON CardNum Names NoteE Month Phone Street4 CityL State Alarm DirectionKeyx Choice2 TopCard LastCard AsciiKey= CleanUpk @ ClearHelpW @ DrawCards EditCard @ InitIndex PrintLabel @ SortIndex SortField ShowViewHelpr ShowTopCard WorkCard( ShowEditHelp ShowCmdLine @ ShowCards EditString InString) Length{ NextField FindCard Prompt Column( SelectField MemoryErr Index Card.CardNum\ CardScreen ViewHelp EditHelpX FieldPositions UserChoice WorkCard.CardNum WorkCard.NamesJ WorkCard.Note WorkCard.Montho WorkCard.Day WorkCard.Year WorkCard.Phone WorkCard.Street WorkCard.City` WorkCard.State WorkCard.Zip3 NextFlag* Card.Names Card.NoteF Card.Month Card.DayS Card.Year Card.Phone Card.Street Card.City Card.State Card.Zip> Insert Workw FirstTime TmpCard NotFirst TmpCard.Names TmpCard.Note TmpCard.Phone TmpCard.Street TmpCard.City TmpCard.State= TmpCard.Zip Found Record FieldNumr Count Offset Limit Switch drawcard` Define English names for color-specification numbers. Add BRIGHT to * QCards - A simple database using a cardfile user interface. * Each record in the database is represented by a card. The user * can scroll through the cards using normal scrolling keys. * Other commands allow the user to edit, add, sort, find, or * delete cards.s * Input: Keyboard - user commands and entries File - database recordso * Output: Screen - card display and help File - database recordsp The module-level code begins here. * Declarations and definitions begin here Resets the default data type from single precision to integer Define names similar to keyboard names with their equivalent key codes. Define English names for color-specification numbers. Add BRIGHT to any color to get bright version.p Assign colors to different kinds of text. By changing the color assigned, you can change the color of the QCARDS display. The initial colors aree chosen because they work for color or black-and-white displays. Codes for normal and highlight (used in data statements)s Screen positions - Initialized for 25 rows. Screen positions can be modified for 43-row mode if you have an EGA or VGA adapter. Miscellaneous symbolic constantsh File names $$$87y$.$5$" Unlikely file nameE Field names Declare user-defined type (a data structure) for random-access file records. First element is card number Names (in order for alphabetical sort) Note about persono Birth montht Birth dayt Birth year Phone number Street address State Zip code SUB procedure declarations begin here.e This space reserved e FUNCTION procedure declarations begin here. Procedure declarations end here.b Define temporary Index() array to illustrate QCARDS screen. Define a dummy record as a work card. * Declarations and definitions end here The execution-sequence logic of QCARDS begins here. Open data file QCARDS.DAT for random access using file #1 To count records in file, divide the length of the file by the length of a single record; use integer division (\) instead of normal division (/). Assign the resulting value to LastCard.o Redefine the Index array to hold the records in the file plus 20 extra (the extra records allow the user to add cards). This array is dynamic - this means the number of elements in Index() varies depending on the size of the file.m Also, Index() is a shared procedure, so it is available to all SUB and FUNCTION procedures in the program. Note that an error trap lets QCARDS terminate with an error message if the memory available is not sufficient. If nor error is detected, the error trap is turned off following the REDIM statement.d Use the block IF...THEN...ELSE statement to decide whethert to load the records from the disk file QCARDS.DAT into thet array of records called Index() declared earlier. In the IF part, you will check to see if there are actually records in the file. If there are, LastCard will be greater than 0, and you can call the InitIndex procedure to load the records into Index(). LastCard is 0 if there are no records in thed file yet. If there are no records in the file, the ELSE clause is executed. The code between ELSE and END IF starts the Index() array at card 1. Use the DrawCards procedure to initialize the screen and draw the cards. Then, set the first card as the top card. Finally, pass the variables TopCard and LastCardp as arguments to the ShowCards procedure. The call tor ShowCards places all the data for TopCard on the front card on the screen, then it places the top-line information (the person's name) on the remaining cards. Keep the picture on the screen forever with an unconditional DO...LOOP statement. The DO part of the statement goes on the next code line. The LOOP part goes just before the END statement. This loop encloses the central logic that lets a user interact with QCARDS.s Get user keystroke with a conditional DO...LOOP statement. Within the loop, use the INKEY$ function to capture a user keystroke, which is then assigned to a string variable. The WHILE part of the LOOP line keeps testing the stringl variable. Until a key is pressed, INKEY$ keeps returning ae null (that is a zero-length) string, represented by "". When a key is pressed, INKEY$ returns a string with a length greater than zero, and the loop terminates.h Use the LEN function to find out whether Choice$ is greater than a single character (i.e. a single byte). If Choice$ is a single character (that is, it is less than 2 bytes long), the key pressed was an ordinary "typewriter keyboard" character (these are usually called ASCII keys because they are part of the ASCII character set). When the user entersy an ASCII character, it indicates a choice of one of the QCARDS commands from the command line at the bottom of the screen. If the user did press an ASCII key, use the LCASE$ function to convert it to lower case (in the event the capital letter was entered). The ELSE clause is only executed if Choice$ is longer than a single character (and therefore not a command-line key).a If Choice$ is not an ASCII key, it represents an "extended" key. (The extended keys include the DIRECTION keys on the numeric keypad, which is why QCARDS looks for them.) Thee RIGHT$ function is then used trim away the extra byte,h leaving a value that may correspond to one of the DIRECTION keys. Use a SELECT CASE construction to respond to those key- presses that represent numeric-keypad DIRECTION keys. Adjust the cards according to the key pressed by the user,l then call the ShowCards procedure to show adjusted stack. This is the bottom of the unconditional DO loop.e The execution sequence of the module-level code ends here. The program may terminate elsewhere for legitimate reasons, but the normal execution sequence ends here. Statements beyond the END statement are executed only in response to other statements. This first label, MemoryErr, is an error handler. Not enough memory. Can't read file." Data statements for screen output - initialized for 25 rows. Can be modified for 43-row mode if you have an EGA or VGA adapter. " J " " " "! " j! " ! " ! " B" " " " " " # " _____________________________________ Note: _______________________________ Birth: __/__/__ Phone: ___-___-____ Street: _____________________________ City: ____________ ST: __ Zip: _____ Color codes and strings for view-mode help" & 0, "Select card with:" && 1, " UP" @& 1, " DOWN" Z& 1, " PGUP" t& 1, " PGDN" & 1, " HOME" & 1, " END" & 1, "" ' 1, "" Color codes and strings for edit-mode help" ' 0, "Next field:" 8' 1, " TAB" T' 0, "Accept card:" n' 1, " ENTER" ' 0, "Edit field:" ' 1, " DEL BKSP" ' 1, " RIGHT LEFT" ' 1, " HOME END" F( 1, " INS ESC" Row, column, and length of each field ~( 14, 6, 37 Names ( 16, 12, 31 Notes ( 18, 13, 2 Month $) 18, 16, 2 \) 18, 19, 2 Year ) 18, 31, 12 Phone ) 20, 14, 29 Street * 22, 12, 13 Citye >* 22, 29, 2 State t* 22, 38, 5 0, 0, 0 AsciiKey * AsciiKey - Handles ASCII keys. You can add new commands by * assigning keys and actions here and adding them to the command * line displayed by the ShowCmdLine SUB. For example, you could adde * L (for Load new file) to prompt the user for a new database file.e * Params: UserChoice$ - key pressed by the usera TopCard - the number of the current record LastCard - the number of records Edit the current card. Editing Card..." Add and edit a blank or duplicate card. Duplicate of top card Initialize new card. Editing Card..." Move deleted card to end and adjust last card.d Find a specified card. Enter fields for search (blank fields are ignored) Can't find card. Press any key..." Sorts cards by a specified field. TAB to desired sort field, then press ENTER" Prints address of top card on printer.E Terminates the program. CleanUp * CleanUp - Writes all records from memory to a file. Deletedr * records (past the last card) will not be written. The valid records * are written to a temporary file. The old file is deleted, and thed * new file is given the old name.. * Params: LastCard - the number of valid records * Output: Valid records to "QCARDS.DAT" through TMPFILE$ Write records to temporary file in their current sort order.n Delete old file and replace it with new version. QCARDS.DAT QCARDS.DAT ClearHelp * ClearHelp - Writes spaces to the help area of the screen.r * Params: None * Output: Blanks to the screen Clear key helps Clear command line DrawCards * DrawCards - Initializes screen by setting the color, setting the width * and height, clearing the screen, and hiding the cursor. Then writes card * text and view-mode help to the screen. * Params: None * Output: Text to the screen Clear screen to current color.e Display line characters that form cards. Display help. EditCard * EditCard - Edits each field of a specified record. * Params: Card - the record to be edited * Return: Since Card is passed by reference, the edited version is effectively returned.a Set NextFlag and continue editing each field. NextFlag is cleared when the user presses ENTER.e Start with first field. Edit string fields directly. Result of edit determines whether to continue. Convert numeric fields to strings for editing. Convert result back to number. InitIndex * InitIndex - Reads records from file and assigns each value to. * array records. Index values are set to the actual order of the * records in the file. The order of records in the array may changer * because of sorting or additions, but the CardNum field alwaysa * has the position in which the record actually occurs in the file.r * Params: LastCard - number of records in array * Input: File "QCARDS.DAT"" Read a record from the file and put each field in the array. PrintLabel * PrintLabel - Prints the name, address, city, state, and zip code from * a card. This SUB could easily be modified to print a return addresso * or center the address on an envelope.f * Params: Card - all the data about a person * Output: Printera SortIndex * SortIndex - Sorts all records in memory according to a specified * field. After the sort, the first record in memory becomes the top * card. Note that although the order is changed in memory, the order * remains the same in the file. The true file order is shown by ther * CardNum field of each record. This SUB uses the Shell sort algorithm.e * Params: SortField - 0-based number of the field to sort on LastCard - number of last card Set comparison offset to half the number of records.s Loop until offset gets to zero. Assume no switches at this offset.n Compare elements for the specified field and switch any that are out of order.p Sort on next pass only to location where last switch was made.g No switches at last offset. Try an offset half as big.a ShowViewHelp * ShowViewHelp - Reads colors and strings for view-mode help and * puts them on screen. * Params: None * Output: Screen Clear old help and display new. Restore color and show command line.i ShowTopCard * ShowTopCard - Shows all the fields of the top card.d * Params: WorkCard - record to be displayed as top card * Output: Screen Display each field of current card. ShowEditHelp * ShowEditHelp - Reads colors and strings for edit-mode help and * puts them on screen. * Params: None * Output: Screen Clear old help and display new. Restore normal color. ShowCmdLine * ShowCmdLine - Puts command line on screen with highlighted key * characters. Modify this SUB if you add additional commands.k * Params: None * Output: Screen dit Top dd New " opy to New " elete ind ort rint " ShowCards * ShowCards - Shows all the fields of the top card and the top * field of the other visible cards.o * Params: TopCard - number of top card LastCard - number of last card * Output: Screen Show each field of top card. Show the Names field for other visible cards. Show location and card number for next highest card.d EditString * EditString$ - Edits a specified string. This function * implements a subset of editing functions used in the QuickBASICs * environment and in Windows. Common editing keys are recognized,s * including direction keys, DEL, BKSP, INS (for insert and overwrite * modes), ESC, and ENTER. TAB is recognized only if the NextFieldi * flag is set. CTRL-key equivalents are recognized for most keys.i * A null string can be specified if no initial value is desired. * You could modify this function to handle additional QB edite * commands, such as CTRL+A (word back) and CTRL+F (word forward). * Params: InString$ - The input string (can be null) Length - Maximum length of string (the function beeps andr refuses additional keys if the user tries to enter more) NextField - Flag indicating on entry whether to accept TAB key; on exit, indicates whether the user pressed TAB (TRUE) or ENTER (FALSE) * Input: Keyboard * Ouput: Screen - Noncontrol keys are echoed. Speaker - beep if key is invalid or string is too long * Return: The edited strings Initialize variables and clear field to its maximum length. Since Insert is STATIC, its value is maintained from onet call to the next. Insert is 0 (FALSE) the first time thet function is called. Reverse video on entry. Process keys until either TAB or ENTER is pressed.m Get a key -- either a one-byte ASCII code or a two-byte extended code.i Translate two-byte extended codes to the one meaningful byte. Translate extended codes to ASCII control codes.n Handle HOME and END keys, since they don't have control codes. Send NULL as a signal to ignore. Make other key choices invalid. Handle one-byte ASCII codes.i If it is null, ignore it. Accept field (and card if NextField is used). Accept the field unless NextField is used. If NextField is cleared, TAB is invalid. Restore the original string. CTRL+S or LEFT arrow moves cursor to left. CTRL+D or RIGHT arrow moves cursor to right. CTRL+G or DEL deletes character under cursor. CTRL+H or BKSP deletes character to left of cursor. CTRL+V or INS toggles between insert and overwrite modes. Echo ASCII characters to screen.s Clear the field if this is first keystroke, thent start from the beginning. If insert mode and cursor not beyond end, insert character. If overwrite mode and cursor at end (but not beyond), insert character. If overwrite mode and before end, overwrite character. Consider other key choices invalid. Print the modified string. Print the final string and assign it to function name. FindCard * FindCard - Finds a specified record. The user specifies as many * fields to search for as desired. The search begins at the card * after the current card and proceeds until the specified record or * the current card is reached. Specified records are retained between * calls to make repeat searching easier. This SUB could be enhancede * to find partial matches of string fields.i * Params: TopCard - number of top card LastCard - number of last card * Params: None * Return: Number (zero-based) of the selected fieldo Initialize string fields to null on the first call. (Note that thee variables TmpCard and NotFirst, declared STATIC above, retain their values between subsequent calls.) Show top card, then use EditCardFunction to specify fieldsa for search. Search until a match is found or all cards have been checked. Test name to see if it's a match. Test note text. Test month. Test day. Test year. Test phone number. Test street address. Test city. Test state. Test zip code. If match is found, set function value and quit, else next card. Return FALSE when no match is found.e Prompt * Prompt$ - Prints a prompt at a specified location on the screen ando * (optionally) gets a user response. This function can take one of three * different actions depending on the length parameter. * Params: Msg$ - message or prompt (can be "" for no message)n Row Column Length - one of the following: <1 - Don't wait for response 1 - Get character response >1 - Get string response up to lengthe * Output: Keyboard * Output: Screen - noncontrol characters echoedo * Return: String entered by user No return Character return String return SelectField * SelectField - Enables a user to select a field using TAB key. * TAB moves to the next field. ENTER selects the current field. * Params: None * Return: Number (zero-based) of the selected fieldr Get first cursor position and set first FieldNum. Rotate cursor through fields. Set cursor on current field.. Get a TAB or ENTER. If ENTER pressed, turn off cursor and return field. Otherwise, it was TAB, so advance to next field.l